package com.jh.paymentchannel.util.yipiaolian;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.FileInputStream;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.cert.*;
import java.util.*;

public class SecurityUtils {
    /**
     * 排序
     * 方法仅供参考
     * @param parameters 需要发送的参数
     * @return
     */
    public static String sort(Map<String, String> parameters) {
        StringBuffer sb = new StringBuffer();
        Set<Map.Entry<String,String>> es = parameters.entrySet();
        Iterator<Map.Entry<String,String>> it = es.iterator();
        while (it.hasNext()) {
            Map.Entry<String,String> entry = (Map.Entry<String,String>)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if ((v != null) && (!"".equals(v)) && (!"sign".equals(k)) && (!"key".equals(k))) {
                sb.append(k + "=" + v + "&");
            }
        }
        String dataString = sb.toString();
        return dataString.substring(0, dataString.length() - 1);
    }

    /**
     * 获取私钥
     * @param keyStoreFilePath keyStore 路径
     * @param keyStorePassword keyStore 密码
     * @param privateKeyPwd 私钥密码
     * @return
     * @throws Exception
     */
    public static PrivateKey getPrivateKey(String keyStoreFilePath, String keyStorePassword, String privateKeyPwd) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(keyStoreFilePath), keyStorePassword.toCharArray());
        Enumeration<String> aliases = keyStore.aliases();
        String alias = "";
        while(aliases.hasMoreElements()) {
            alias = aliases.nextElement();
        }
        return (PrivateKey)keyStore.getKey(alias, privateKeyPwd.toCharArray());
    }

    /**
     * 获取公钥
     * @param certFilePath
     * @return
     * @throws Exception
     */
    public static PublicKey getPublicKey(String certFilePath) throws Exception {
        FileInputStream in = new FileInputStream(certFilePath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        java.security.cert.Certificate cert = cf.generateCertificate(in);
        PublicKey publicKey = cert.getPublicKey();
        return publicKey;
    }

    /**
     * 签名
     * @param dataString 已经排好序的 String
     * @param privateKey 从yzt.pfx取出私钥
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws SignatureException
     * @throws UnsupportedEncodingException
     */
    public static byte[] sign(String dataString, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(dataString.getBytes("UTF-8"));
        return signature.sign();
    }


    /**
     * 解签
     * @param map 收到的报文参数
     * @param publicKey 从epaylinks_pfx.cer取出公钥
     * @return
     * @throws Exception
     */
    public static boolean unSign(SortedMap map, PublicKey publicKey) throws Exception {
        StringBuffer sb = new StringBuffer();
        Set<Map.Entry<String ,String>> es = map.entrySet();
        Iterator<Map.Entry<String ,String>> it = es.iterator();
        while(it.hasNext())
        {
            Map.Entry<String ,String> entry = (Map.Entry<String ,String>)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if(!"sign".equals(k) && null != v && !"".equals(v))
            {
                sb.append(k + "=" + v + "&");
            }
        }
        String dataString = sb.toString();
        dataString = dataString.substring(0,dataString.length()-1);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);
        signature.update(dataString.getBytes("utf-8"));
        return signature.verify(new BASE64Decoder().decodeBuffer((String) map.get("sign")));
    }

    public static String getCertId(KeyStore keyStore) throws KeyStoreException {
        Enumeration<String> aliases = keyStore.aliases();
        String alias = "";
        while(aliases.hasMoreElements()) {
            alias = aliases.nextElement();
        }
        X509Certificate certificate = (X509Certificate)keyStore.getCertificate(alias);
        return certificate.getSerialNumber().toString();
    }

    public static String getEncryptedInfo(PublicKey publicKey, String CVN2, String expired) throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        String clearText = "cvn2="+CVN2+"&expired="+expired;
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(1, publicKey);
        byte[] r1 = cipher.doFinal(clearText.getBytes("UTF-8"));
        String encryptedInfo = new BASE64Encoder().encode(r1).replaceAll("[\\s*\t\n\r]", "");
        return encryptedInfo;
    }
    
    /**
     * 获取证书序列号
     * @param keyStoreFilePath
     * @param keyStorePassword
     * @return
     * @throws Exception
     */
    public static String getCertId(String keyStoreFilePath, String keyStorePassword) throws Exception {
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new FileInputStream(keyStoreFilePath), keyStorePassword.toCharArray());
        Enumeration<String> aliase = keyStore.aliases();
        String keyAlias = null;
        if (aliase.hasMoreElements()) {
            keyAlias = aliase.nextElement();
        }
        X509Certificate cert = (X509Certificate) keyStore
                .getCertificate(keyAlias);
        return cert.getSerialNumber().toString();
    }

    
    
    
}
